package com.leoman.statData.service.impl;

import com.leoman.category.entity.Category;
import com.leoman.common.service.impl.GenericManagerImpl;
import com.leoman.post.dao.PostBaseDao;
import com.leoman.post.dao.PostTypeDataDao;
import com.leoman.post.entity.PostTypeData;
import com.leoman.resources.dao.*;
import com.leoman.resources.entity.*;
import com.leoman.statData.service.StatDataService;
import com.leoman.utils.ImageUtil;
import com.leoman.welfare.dao.WelfareDao;
import com.leoman.welfare.dao.WelfareDataDao;
import com.leoman.welfare.entity.Welfare;
import com.leoman.welfare.entity.WelfareData;
import com.leoman.work.dao.*;
import com.leoman.work.entity.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 数据统计ServiceImpl
 * Created by 涂奕恒 on 2016/12/15 0022.
 */
@Service
public class StatDataServiceImpl extends GenericManagerImpl<WorkData, WorkDataDao> implements StatDataService {

    @Autowired
    private WorkDataDao workDataDao;

    @Autowired
    private WorkVideoDao workVideoDao;

    @Autowired
    private WorkNovelDao workNovelDao;

    @Autowired
    private WorkComicDao workComicDao;

    @Autowired
    private PostTypeDataDao postTypeDataDao;

    @Autowired
    private ResourceDataDao resourceDataDao;

    @Autowired
    private StillResourceDao stillResourceDao;

    @Autowired
    private MusicResourceDao musicResourceDao;

    @Autowired
    private GameResourcesDao gameResourcesDao;

    @Autowired
    private ResourceDetailDataDao resourceDetailDataDao;

    @Autowired
    private WelfareDataDao welfareDataDao;

    @Autowired
    private WelfareDao welfareDao;

    @Autowired
    private PostBaseDao postBaseDao;

    @Autowired
    private WorkDao workDao;

    @Override
    @Transactional
    public Page<WorkData> pageWorkList(Integer type, String name, Integer pageNum, Integer pageSize) {
        PageRequest pageRequest = new PageRequest(pageNum - 1, pageSize);
        final Page<Work> page;

        if (StringUtils.isBlank(name)) {
            page = workDao.pageByType(type, pageRequest);
        } else {
            page = workDao.pageByParams(type, "%" + name + "%", pageRequest);
        }

        return new Page<WorkData>() {
            @Override
            public int getNumber() {
                return page.getNumber();
            }

            @Override
            public int getSize() {
                return page.getSize();
            }

            @Override
            public int getTotalPages() {
                return page.getTotalPages();
            }

            @Override
            public int getNumberOfElements() {
                return page.getNumberOfElements();
            }

            @Override
            public long getTotalElements() {
                return page.getTotalElements();
            }

            @Override
            public boolean hasPreviousPage() {
                return page.hasPreviousPage();
            }

            @Override
            public boolean isFirstPage() {
                return page.isFirstPage();
            }

            @Override
            public boolean hasNextPage() {
                return page.hasNextPage();
            }

            @Override
            public boolean isLastPage() {
                return page.isLastPage();
            }

            @Override
            public Pageable nextPageable() {
                return page.nextPageable();
            }

            @Override
            public Pageable previousPageable() {
                return page.previousPageable();
            }

            @Override
            public Iterator<WorkData> iterator() {
                final Iterator<Work> iterator = page.iterator();
                return new Iterator<WorkData>() {
                    @Override
                    public boolean hasNext() {
                        return iterator.hasNext();
                    }

                    @Override
                    public WorkData next() {
                        return changeWorkData(iterator.next());
                    }
                };
            }

            @Override
            public List<WorkData> getContent() {
                List<Work> workList = page.getContent();
                List<WorkData> list = new ArrayList<>();

                for (Work work : workList) {
                    list.add(changeWorkData(work));
                }

                return list;
            }

            @Override
            public boolean hasContent() {
                return page.hasContent();
            }

            @Override
            public Sort getSort() {
                return page.getSort();
            }
        };
    }

    private WorkData changeWorkData(Work work) {
        WorkData workData = new WorkData();
        workData.setWork(work);
        List<WorkData> list = workDataDao.findListByWorkId(work.getId());
        for (WorkData tempWorkData : list) {
            workData.setAllPlayNum(workData.getAllPlayNum() + tempWorkData.getPlayNum());
            workData.setAllBarrageNum(workData.getAllBarrageNum() + tempWorkData.getBarrageNum());
        }

        return workData;
    }

    @Override
    public Page<WorkData> pageWorkDetailList(Long workId, Integer type, Integer pageNum, Integer pageSize) {
        PageRequest pageRequest = new PageRequest(pageNum - 1, pageSize);

        if (type == 4) {
            final Page<WorkVideo> workVideoPage = workVideoDao.pageByWorkId(workId, pageRequest);

            return new Page<WorkData>() {
                @Override
                public int getNumber() {
                    return workVideoPage.getNumber();
                }

                @Override
                public int getSize() {
                    return workVideoPage.getSize();
                }

                @Override
                public int getTotalPages() {
                    return workVideoPage.getTotalPages();
                }

                @Override
                public int getNumberOfElements() {
                    return workVideoPage.getNumberOfElements();
                }

                @Override
                public long getTotalElements() {
                    return workVideoPage.getTotalElements();
                }

                @Override
                public boolean hasPreviousPage() {
                    return workVideoPage.hasPreviousPage();
                }

                @Override
                public boolean isFirstPage() {
                    return workVideoPage.isFirstPage();
                }

                @Override
                public boolean hasNextPage() {
                    return workVideoPage.hasNextPage();
                }

                @Override
                public boolean isLastPage() {
                    return workVideoPage.isLastPage();
                }

                @Override
                public Pageable nextPageable() {
                    return workVideoPage.nextPageable();
                }

                @Override
                public Pageable previousPageable() {
                    return workVideoPage.previousPageable();
                }

                @Override
                public Iterator<WorkData> iterator() {
                    final Iterator<WorkVideo> workVideoIterator = workVideoPage.iterator();
                    return new Iterator<WorkData>() {
                        @Override
                        public boolean hasNext() {
                            return workVideoIterator.hasNext();
                        }

                        @Override
                        public WorkData next() {
                            return changeWorkData(workVideoIterator.next().getWork(), workVideoIterator.next().getId(), workVideoIterator.next(), null, null);
                        }
                    };
                }

                @Override
                public List<WorkData> getContent() {
                    List<WorkVideo> workVideoList = workVideoPage.getContent();
                    List<WorkData> list = new ArrayList<>();

                    for (WorkVideo workVideo : workVideoList) {
                        list.add(changeWorkData(workVideo.getWork(), workVideo.getId(), workVideo, null, null));
                    }

                    return list;
                }

                @Override
                public boolean hasContent() {
                    return workVideoPage.hasContent();
                }

                @Override
                public Sort getSort() {
                    return workVideoPage.getSort();
                }
            };
        } else if (type == 5) {
            final Page<WorkNovel> workNovelPage = workNovelDao.pageByWorkId(workId, pageRequest);

            return new Page<WorkData>() {
                @Override
                public int getNumber() {
                    return workNovelPage.getNumber();
                }

                @Override
                public int getSize() {
                    return workNovelPage.getSize();
                }

                @Override
                public int getTotalPages() {
                    return workNovelPage.getTotalPages();
                }

                @Override
                public int getNumberOfElements() {
                    return workNovelPage.getNumberOfElements();
                }

                @Override
                public long getTotalElements() {
                    return workNovelPage.getTotalElements();
                }

                @Override
                public boolean hasPreviousPage() {
                    return workNovelPage.hasPreviousPage();
                }

                @Override
                public boolean isFirstPage() {
                    return workNovelPage.isFirstPage();
                }

                @Override
                public boolean hasNextPage() {
                    return workNovelPage.hasNextPage();
                }

                @Override
                public boolean isLastPage() {
                    return workNovelPage.isLastPage();
                }

                @Override
                public Pageable nextPageable() {
                    return workNovelPage.nextPageable();
                }

                @Override
                public Pageable previousPageable() {
                    return workNovelPage.previousPageable();
                }

                @Override
                public Iterator<WorkData> iterator() {
                    final Iterator<WorkNovel> workNovelIterator = workNovelPage.iterator();
                    return new Iterator<WorkData>() {
                        @Override
                        public boolean hasNext() {
                            return workNovelIterator.hasNext();
                        }

                        @Override
                        public WorkData next() {
                            return changeWorkData(workNovelIterator.next().getWork(), workNovelIterator.next().getId(), null, workNovelIterator.next(), null);
                        }
                    };
                }

                @Override
                public List<WorkData> getContent() {
                    List<WorkNovel> workNovelList = workNovelPage.getContent();
                    List<WorkData> list = new ArrayList<>();

                    for (WorkNovel workNovel : workNovelList) {
                        list.add(changeWorkData(workNovel.getWork(), workNovel.getId(), null, workNovel, null));
                    }

                    return list;
                }

                @Override
                public boolean hasContent() {
                    return workNovelPage.hasContent();
                }

                @Override
                public Sort getSort() {
                    return workNovelPage.getSort();
                }
            };
        } else {
            final Page<WorkComic> workComicPage = workComicDao.pageByWorkId(workId, pageRequest);

            return new Page<WorkData>() {
                @Override
                public int getNumber() {
                    return workComicPage.getNumber();
                }

                @Override
                public int getSize() {
                    return workComicPage.getSize();
                }

                @Override
                public int getTotalPages() {
                    return workComicPage.getTotalPages();
                }

                @Override
                public int getNumberOfElements() {
                    return workComicPage.getNumberOfElements();
                }

                @Override
                public long getTotalElements() {
                    return workComicPage.getTotalElements();
                }

                @Override
                public boolean hasPreviousPage() {
                    return workComicPage.hasPreviousPage();
                }

                @Override
                public boolean isFirstPage() {
                    return workComicPage.isFirstPage();
                }

                @Override
                public boolean hasNextPage() {
                    return workComicPage.hasNextPage();
                }

                @Override
                public boolean isLastPage() {
                    return workComicPage.isLastPage();
                }

                @Override
                public Pageable nextPageable() {
                    return workComicPage.nextPageable();
                }

                @Override
                public Pageable previousPageable() {
                    return workComicPage.previousPageable();
                }

                @Override
                public Iterator<WorkData> iterator() {
                    final Iterator<WorkComic> workComicIterator = workComicPage.iterator();
                    return new Iterator<WorkData>() {
                        @Override
                        public boolean hasNext() {
                            return workComicIterator.hasNext();
                        }

                        @Override
                        public WorkData next() {
                            return changeWorkData(workComicIterator.next().getWork(), workComicIterator.next().getId(), null, null, workComicIterator.next());
                        }
                    };
                }

                @Override
                public List<WorkData> getContent() {
                    List<WorkComic> workComicList = workComicPage.getContent();
                    List<WorkData> list = new ArrayList<>();

                    for (WorkComic workComic : workComicList) {
                        list.add(changeWorkData(workComic.getWork(), workComic.getId(), null, null, workComic));
                    }

                    return list;
                }

                @Override
                public boolean hasContent() {
                    return workComicPage.hasContent();
                }

                @Override
                public Sort getSort() {
                    return workComicPage.getSort();
                }
            };
        }
    }

    private WorkData changeWorkData(Work work, Long detailId, WorkVideo workVideo, WorkNovel workNovel, WorkComic workComic) {
        WorkData workData = new WorkData();
        workData.setId(detailId);
        workData.setWork(work);

        switch (work.getCategory().getType()) {
            case 4:
                workData.setSeriesCount(workVideo.getSeries());
                workData.setSeriesName(workVideo.getName());
                workData.setUpdateTime(workVideo.getCreateDate());
                break;
            case 5:
                workData.setSeriesCount(workNovel.getSeries());
                workData.setSeriesName(workNovel.getName());
                workData.setUpdateTime(workNovel.getCreateDate());
                break;
            case 6:
                workData.setSeriesCount(workComic.getSeries());
                workData.setSeriesName(workComic.getName());
                workData.setUpdateTime(workComic.getCreateDate());
                break;
        }

        List<WorkData> list = workDataDao.findListByWorkIdAndDetailId(work.getId(), detailId);
        for (WorkData tempData : list) {
            workData.setAllPlayNum(workData.getAllPlayNum() + tempData.getPlayNum());
            workData.setAllBarrageNum(workData.getAllBarrageNum() + tempData.getBarrageNum());
        }

        return workData;
    }

    @Override
    public Page<WorkData> pageWorkDetailListPlus(Long workId, Long detailId, String startDate, String endDate, Integer pageNum, Integer pageSize) {
        PageRequest pageRequest = new PageRequest(pageNum - 1, pageSize);
        return workDataDao.pageByWorkIdAndDetailIdAndAllDate(workId, detailId, startDate, endDate, pageRequest);
    }

    @Override
    public Page<PostTypeData> pageByParams(String typeName, Integer pageNum, Integer pageSize) {
        PageRequest pageRequest = new PageRequest(pageNum - 1, pageSize);

        final Page<Category> categoryPage;

        if (StringUtils.isNotBlank(typeName)) {
            categoryPage = postBaseDao.pageByType("%" + typeName + "%", pageRequest);
        } else {
            categoryPage = postBaseDao.pageByNone(pageRequest);
        }

        return new Page<PostTypeData>() {
            @Override
            public int getNumber() {
                return categoryPage.getNumber();
            }

            @Override
            public int getSize() {
                return categoryPage.getSize();
            }

            @Override
            public int getTotalPages() {
                return categoryPage.getTotalPages();
            }

            @Override
            public int getNumberOfElements() {
                return categoryPage.getNumberOfElements();
            }

            @Override
            public long getTotalElements() {
                return categoryPage.getTotalElements();
            }

            @Override
            public boolean hasPreviousPage() {
                return categoryPage.hasPreviousPage();
            }

            @Override
            public boolean isFirstPage() {
                return categoryPage.isFirstPage();
            }

            @Override
            public boolean hasNextPage() {
                return categoryPage.hasNextPage();
            }

            @Override
            public boolean isLastPage() {
                return categoryPage.isLastPage();
            }

            @Override
            public Pageable nextPageable() {
                return categoryPage.nextPageable();
            }

            @Override
            public Pageable previousPageable() {
                return categoryPage.previousPageable();
            }

            @Override
            public Iterator<PostTypeData> iterator() {
                final Iterator<Category> postBaseIterator = categoryPage.iterator();
                return new Iterator<PostTypeData>() {
                    @Override
                    public boolean hasNext() {
                        return postBaseIterator.hasNext();
                    }

                    @Override
                    public PostTypeData next() {
                        return changeCategoryData(postBaseIterator.next());
                    }
                };
            }

            @Override
            public List<PostTypeData> getContent() {
                List<Category> postBaseList = categoryPage.getContent();
                List<PostTypeData> list = new ArrayList<>();

                for (Category category : postBaseList) {
                    list.add(changeCategoryData(category));
                }

                return list;
            }

            @Override
            public boolean hasContent() {
                return categoryPage.hasContent();
            }

            @Override
            public Sort getSort() {
                return categoryPage.getSort();
            }
        };
    }

    private PostTypeData changeCategoryData(Category category) {
        PostTypeData postTypeData = new PostTypeData();
        postTypeData.setCategory(category);
        List<PostTypeData> list;
        Integer playNum;
        Integer sendNum;

        postTypeData.setCount(postTypeDataDao.findPostBaseListByCategoryId(postTypeData.getCategory().getId()).size());

        list = postTypeDataDao.findListByCategoryId(postTypeData.getCategory().getId());
        playNum = 0;
        sendNum = 0;
        for (PostTypeData tempWorkData : list) {
            playNum += tempWorkData.getPlayNum();
            sendNum += tempWorkData.getSendNum();
        }

        postTypeData.setAllPlayNum(playNum);
        postTypeData.setAllSendNum(sendNum);

        return postTypeData;
    }

    @Override
    public Page<PostTypeData> pagePostList(Long categoryId, String startDate, String endDate, Integer pageNum, Integer pageSize) {
        return postTypeDataDao.pageByCategoryId(categoryId, startDate, endDate, new PageRequest(pageNum - 1, pageSize));
    }

    @Override
    public Page<ResourceData> pageResourceList(Integer type, Long resourceId, String resourceName, final String startDate, final String endDate, Integer pageNum, Integer pageSize) {
        PageRequest pageRequest = new PageRequest(pageNum - 1, pageSize);

        if (type == 1) {
            final Page<StillResource> stillResourcePage = stillResourceDao.pageByParams(pageRequest);

            return new Page<ResourceData>() {
                @Override
                public int getNumber() {
                    return stillResourcePage.getNumber();
                }

                @Override
                public int getSize() {
                    return stillResourcePage.getSize();
                }

                @Override
                public int getTotalPages() {
                    return stillResourcePage.getTotalPages();
                }

                @Override
                public int getNumberOfElements() {
                    return stillResourcePage.getNumberOfElements();
                }

                @Override
                public long getTotalElements() {
                    return stillResourcePage.getTotalElements();
                }

                @Override
                public boolean hasPreviousPage() {
                    return stillResourcePage.hasPreviousPage();
                }

                @Override
                public boolean isFirstPage() {
                    return stillResourcePage.isFirstPage();
                }

                @Override
                public boolean hasNextPage() {
                    return stillResourcePage.hasNextPage();
                }

                @Override
                public boolean isLastPage() {
                    return stillResourcePage.isLastPage();
                }

                @Override
                public Pageable nextPageable() {
                    return stillResourcePage.nextPageable();
                }

                @Override
                public Pageable previousPageable() {
                    return stillResourcePage.previousPageable();
                }

                @Override
                public Iterator<ResourceData> iterator() {
                    final Iterator<StillResource> stillResourceIterator = stillResourcePage.iterator();
                    return new Iterator<ResourceData>() {
                        @Override
                        public boolean hasNext() {
                            return stillResourceIterator.hasNext();
                        }

                        @Override
                        public ResourceData next() {
                            return changeResource(stillResourceIterator.next().getId(), 1, startDate, endDate);
                        }
                    };
                }

                @Override
                public List<ResourceData> getContent() {
                    List<StillResource> stillResourceList = stillResourcePage.getContent();
                    List<ResourceData> list = new ArrayList<>();

                    for (StillResource stillResource : stillResourceList) {
                        list.add(changeResource(stillResource.getId(), 1, startDate, endDate));
                    }

                    return list;
                }

                @Override
                public boolean hasContent() {
                    return stillResourcePage.hasContent();
                }

                @Override
                public Sort getSort() {
                    return stillResourcePage.getSort();
                }
            };
        } else if (type == 2) {
            final Page<MusicResource> musicResourcePage;

            if (StringUtils.isBlank(resourceName)) {
                musicResourcePage = musicResourceDao.pageByParams(pageRequest);
            } else {
                musicResourcePage = musicResourceDao.pageByParams("%" + resourceName + "%", pageRequest);
            }

            return new Page<ResourceData>() {
                @Override
                public int getNumber() {
                    return musicResourcePage.getNumber();
                }

                @Override
                public int getSize() {
                    return musicResourcePage.getSize();
                }

                @Override
                public int getTotalPages() {
                    return musicResourcePage.getTotalPages();
                }

                @Override
                public int getNumberOfElements() {
                    return musicResourcePage.getNumberOfElements();
                }

                @Override
                public long getTotalElements() {
                    return musicResourcePage.getTotalElements();
                }

                @Override
                public boolean hasPreviousPage() {
                    return musicResourcePage.hasPreviousPage();
                }

                @Override
                public boolean isFirstPage() {
                    return musicResourcePage.isFirstPage();
                }

                @Override
                public boolean hasNextPage() {
                    return musicResourcePage.hasNextPage();
                }

                @Override
                public boolean isLastPage() {
                    return musicResourcePage.isLastPage();
                }

                @Override
                public Pageable nextPageable() {
                    return musicResourcePage.nextPageable();
                }

                @Override
                public Pageable previousPageable() {
                    return musicResourcePage.previousPageable();
                }

                @Override
                public Iterator<ResourceData> iterator() {
                    final Iterator<MusicResource> musicResourceIterator = musicResourcePage.iterator();
                    return new Iterator<ResourceData>() {
                        @Override
                        public boolean hasNext() {
                            return musicResourceIterator.hasNext();
                        }

                        @Override
                        public ResourceData next() {
                            return changeResource(musicResourceIterator.next().getId(), 2, startDate, endDate);
                        }
                    };
                }

                @Override
                public List<ResourceData> getContent() {
                    List<MusicResource> musicResourceList = musicResourcePage.getContent();
                    List<ResourceData> list = new ArrayList<>();

                    for (MusicResource musicResource : musicResourceList) {
                        list.add(changeResource(musicResource.getId(), 2, startDate, endDate));
                    }

                    return list;
                }

                @Override
                public boolean hasContent() {
                    return musicResourcePage.hasContent();
                }

                @Override
                public Sort getSort() {
                    return musicResourcePage.getSort();
                }
            };
        } else {
            final Page<GameResource> gameResourcePage;

            if (StringUtils.isBlank(resourceName)) {
                gameResourcePage = gameResourcesDao.pageByParams(pageRequest);
            } else {
                gameResourcePage = gameResourcesDao.pageByParams("%" + resourceName + "%", pageRequest);
            }

            return new Page<ResourceData>() {
                @Override
                public int getNumber() {
                    return gameResourcePage.getNumber();
                }

                @Override
                public int getSize() {
                    return gameResourcePage.getSize();
                }

                @Override
                public int getTotalPages() {
                    return gameResourcePage.getTotalPages();
                }

                @Override
                public int getNumberOfElements() {
                    return gameResourcePage.getNumberOfElements();
                }

                @Override
                public long getTotalElements() {
                    return gameResourcePage.getTotalElements();
                }

                @Override
                public boolean hasPreviousPage() {
                    return gameResourcePage.hasPreviousPage();
                }

                @Override
                public boolean isFirstPage() {
                    return gameResourcePage.isFirstPage();
                }

                @Override
                public boolean hasNextPage() {
                    return gameResourcePage.hasNextPage();
                }

                @Override
                public boolean isLastPage() {
                    return gameResourcePage.isLastPage();
                }

                @Override
                public Pageable nextPageable() {
                    return gameResourcePage.nextPageable();
                }

                @Override
                public Pageable previousPageable() {
                    return gameResourcePage.previousPageable();
                }

                @Override
                public Iterator<ResourceData> iterator() {
                    final Iterator<GameResource> gameResourceIterator = gameResourcePage.iterator();
                    return new Iterator<ResourceData>() {
                        @Override
                        public boolean hasNext() {
                            return gameResourceIterator.hasNext();
                        }

                        @Override
                        public ResourceData next() {
                            return changeResource(gameResourceIterator.next().getId(), 3, startDate, endDate);
                        }
                    };
                }

                @Override
                public List<ResourceData> getContent() {
                    List<GameResource> gameResourceList = gameResourcePage.getContent();
                    List<ResourceData> list = new ArrayList<>();

                    for (GameResource gameResource : gameResourceList) {
                        list.add(changeResource(gameResource.getId(), 3, startDate, endDate));
                    }

                    return list;
                }

                @Override
                public boolean hasContent() {
                    return gameResourcePage.hasContent();
                }

                @Override
                public Sort getSort() {
                    return gameResourcePage.getSort();
                }
            };
        }
    }

    @Override
    public Page<ResourceData> pageResourceList(Integer type, Long resourceId, Integer pageNum, Integer pageSize) {
        PageRequest pageRequest = new PageRequest(pageNum - 1, pageSize);
        return resourceDataDao.pageByTypeAndResourceId(type, resourceId, pageRequest);
    }

    private ResourceData changeResource(Long resourceId, Integer type, String startDate, String endDate) {
        ResourceData resourceData = new ResourceData();
        resourceData.setResourceId(resourceId);
        StillResource stillResource;
        MusicResource musicResource;
        GameResource gameResource;
        List<ResourceData> list;

        switch (type) {
            case 1:
                // 剧照
                stillResource = stillResourceDao.findOne(resourceId);
                resourceData.setTypeName(stillResource.getCategory().getName() + " - 剧照");
                if (StringUtils.isNotEmpty(stillResource.getImageUrl())) {
                    resourceData.setUrl(ImageUtil.clearUploadUrl(stillResource.getImageUrl()));
                }
                break;
            case 2:
                // 音乐
                musicResource = musicResourceDao.findOne(resourceId);
                resourceData.setResourceName(musicResource.getName());
                resourceData.setTypeName(musicResource.getCategory().getName());
                break;
            case 3:
                // 游戏
                gameResource = gameResourcesDao.findOne(resourceId);
                list = resourceDataDao.findListByTypeAndResourceId(3, resourceId);
                resourceData.setResourceName(gameResource.getName());
                for (ResourceData tempResourceData : list) {
                    resourceData.setAllPlayNum(resourceData.getAllPlayNum() + tempResourceData.getPlayNum());
                    resourceData.setAllDownloadNum(resourceData.getAllDownloadNum() + tempResourceData.getDownloadNum());
                }
                break;
        }

        if (type != 3) {
            List<ResourceData> dataList = resourceDataDao.findListByParams(resourceId, type, startDate, endDate);
            for (ResourceData data : dataList) {
                resourceData.setAllPlayNum(resourceData.getAllPlayNum() + data.getPlayNum());
                resourceData.setAllDownloadNum(resourceData.getAllDownloadNum() + data.getDownloadNum());
            }
        }

        return resourceData;
    }

    @Override
    public Page<ResourceDetailData> pageGameList(final Long resourceId, final String nickName, final Integer status, Integer pageNum, Integer pageSize) {
        return resourceDetailDataDao.findAll(new Specification<ResourceDetailData>() {
            @SuppressWarnings("ToArrayCallWithZeroLengthArrayArgument")
            @Override
            public Predicate toPredicate(Root<ResourceDetailData> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate result = null;
                List<Predicate> predicateList = new ArrayList<>();

                if (null != resourceId) {
                    predicateList.add(cb.equal(root.get("resourceId").as(Integer.class), resourceId));
                }

                if (StringUtils.isNotBlank(nickName)) {
                    predicateList.add(cb.like(root.get("userInfo").get("nickname").as(String.class), "%" + nickName + "%"));
                }

                if (null != status) {
                    if (status == 1) {
                        predicateList.add(cb.like(root.get("content").as(String.class), "%进入资源%"));
                    } else {
                        predicateList.add(cb.like(root.get("content").as(String.class), "%点击下载%"));
                    }
                }

                if (predicateList.size() > 0) {
                    result = cb.and(predicateList.toArray(new Predicate[]{}));
                }

                if (result != null) {
                    query.where(result);
                }
                return query.getGroupRestriction();
            }

        }, new PageRequest(pageNum - 1, pageSize, Sort.Direction.DESC, "createTime"));
    }

    @Override
    public GameResource findGameByResourceId(Long resourceId) {
        return gameResourcesDao.findOne(resourceId);
    }

    @Override
    public Welfare findWelfareByWelfareId(Long welfareId) {
        return welfareDao.findOne(welfareId);
    }

    @Override
    public Page<WelfareData> pageWelfareList(final Long welfareId, final String resourceName, String startDate, String endDate, Integer pageNum, Integer pageSize) {
        PageRequest pageRequest = new PageRequest(pageNum - 1, pageSize);
        Page<WelfareData> page;

        if (null == welfareId) {
            final Page<Welfare> welfarePage = welfareDao.findAll(pageRequest);

            return new Page<WelfareData>() {
                @Override
                public int getNumber() {
                    return welfarePage.getNumber();
                }

                @Override
                public int getSize() {
                    return welfarePage.getSize();
                }

                @Override
                public int getTotalPages() {
                    return welfarePage.getTotalPages();
                }

                @Override
                public int getNumberOfElements() {
                    return welfarePage.getNumberOfElements();
                }

                @Override
                public long getTotalElements() {
                    return welfarePage.getTotalElements();
                }

                @Override
                public boolean hasPreviousPage() {
                    return welfarePage.hasPreviousPage();
                }

                @Override
                public boolean isFirstPage() {
                    return welfarePage.isFirstPage();
                }

                @Override
                public boolean hasNextPage() {
                    return welfarePage.hasNextPage();
                }

                @Override
                public boolean isLastPage() {
                    return welfarePage.isLastPage();
                }

                @Override
                public Pageable nextPageable() {
                    return welfarePage.nextPageable();
                }

                @Override
                public Pageable previousPageable() {
                    return welfarePage.previousPageable();
                }

                @Override
                public Iterator<WelfareData> iterator() {
                    final Iterator<Welfare> welfareIterator = welfarePage.iterator();
                    return new Iterator<WelfareData>() {
                        @Override
                        public boolean hasNext() {
                            return welfareIterator.hasNext();
                        }

                        @Override
                        public WelfareData next() {
                            return changeWelfare(welfareIterator.next());
                        }
                    };
                }

                @Override
                public List<WelfareData> getContent() {
                    List<Welfare> welfareList = welfarePage.getContent();
                    List<WelfareData> list = new ArrayList<>();

                    for (Welfare welfare : welfareList) {
                        list.add(changeWelfare(welfare));
                    }

                    return list;
                }

                @Override
                public boolean hasContent() {
                    return welfarePage.hasContent();
                }

                @Override
                public Sort getSort() {
                    return welfarePage.getSort();
                }
            };
        } else {
            page = welfareDataDao.pageByWelfareId(welfareId, startDate, endDate, pageRequest);
        }

        return page;
    }

    private WelfareData changeWelfare(Welfare welfare) {
        WelfareData welfareData = new WelfareData();
        welfareData.setWelfare(welfare);

        List<WelfareData> list = welfareDataDao.findListByWelfareId(welfare.getId());
        for (WelfareData tempWelfareData : list) {
            welfareData.setAllPlayNum(welfareData.getAllPlayNum() + tempWelfareData.getPlayNum());
        }

        return welfareData;
    }

    @Override
    public Page<ResourceData> pageResourceList(Integer type, Integer pageNum, Integer pageSize) {
        final List<ResourceData> list = new ArrayList<>();

        if (null == type) {
            list.add(getInfoByType(1));
            list.add(getInfoByType(2));
            list.add(getInfoByType(3));
            list.add(getInfoByType(4));
        } else {
            list.add(getInfoByType(type));
        }

        return new Page<ResourceData>() {
            @Override
            public int getNumber() {
                return 0;
            }

            @Override
            public int getSize() {
                return 0;
            }

            @Override
            public int getTotalPages() {
                return 0;
            }

            @Override
            public int getNumberOfElements() {
                return 0;
            }

            @Override
            public long getTotalElements() {
                return 0;
            }

            @Override
            public boolean hasPreviousPage() {
                return false;
            }

            @Override
            public boolean isFirstPage() {
                return false;
            }

            @Override
            public boolean hasNextPage() {
                return false;
            }

            @Override
            public boolean isLastPage() {
                return false;
            }

            @Override
            public Pageable nextPageable() {
                return null;
            }

            @Override
            public Pageable previousPageable() {
                return null;
            }

            @Override
            public Iterator<ResourceData> iterator() {
                return null;
            }

            @Override
            public List<ResourceData> getContent() {
                return list;
            }

            @Override
            public boolean hasContent() {
                return false;
            }

            @Override
            public Sort getSort() {
                return null;
            }
        };
    }

    private ResourceData getInfoByType(Integer type) {
        ResourceData resourceData = new ResourceData();
        Integer[] count;
        Integer[] countDate;

        switch (type) {
            case 1:
                resourceData.setId(1L);
                resourceData.setResourceName("剧照");
                count = getAllCount(resourceDataDao.findListByType(1), null, false);
                resourceData.setAllPlayNum(count[0]);
                resourceData.setAllDownloadNum(count[1]);
                countDate = getAllCount(1, false);
                resourceData.setPlayNum(countDate[0]);
                resourceData.setDownloadNum(countDate[1]);
                break;
            case 2:
                resourceData.setId(2L);
                resourceData.setResourceName("音乐");
                count = getAllCount(resourceDataDao.findListByType(2), null, false);
                resourceData.setAllPlayNum(count[0]);
                resourceData.setAllDownloadNum(count[1]);
                countDate = getAllCount(2, false);
                resourceData.setPlayNum(countDate[0]);
                resourceData.setDownloadNum(countDate[1]);
                break;
            case 3:
                resourceData.setId(3L);
                resourceData.setResourceName("游戏");
                count = getAllCount(resourceDataDao.findListByType(3), null, false);
                resourceData.setAllPlayNum(count[0]);
                resourceData.setAllDownloadNum(count[1]);
                countDate = getAllCount(3, false);
                resourceData.setPlayNum(countDate[0]);
                resourceData.setDownloadNum(countDate[1]);
                break;
            case 4:
                resourceData.setId(4L);
                resourceData.setResourceName("福利社");
                count = getAllCount(null, welfareDataDao.findAll(), true);
                resourceData.setAllPlayNum(count[0]);
                resourceData.setAllDownloadNum(count[1]);
                countDate = getAllCount(3, true);
                resourceData.setPlayNum(countDate[0]);
                resourceData.setDownloadNum(countDate[1]);
                break;
        }

        return resourceData;
    }

    private Integer[] getAllCount(List<ResourceData> list, List<WelfareData> list2, Boolean isWelfare) {
        Integer[] count = new Integer[2];
        Integer count1 = 0;
        Integer count2 = 0;

        if (isWelfare) {
            for (WelfareData welfareData : list2) {
                count1 += welfareData.getPlayNum();
            }
        } else {
            for (ResourceData resourceData : list) {
                count1 += resourceData.getPlayNum();
                count2 += resourceData.getDownloadNum();
            }
        }

        count[0] = count1;
        count[1] = count2;

        return count;
    }

    private Integer[] getAllCount(Integer type, Boolean isWelfare) {
        Integer[] count = new Integer[2];
        Integer count1 = 0;
        Integer count2 = 0;

        if (isWelfare) {
            List<WelfareData> list = welfareDataDao.findAll();

            for (WelfareData welfareData : list) {
                count1 += welfareData.getPlayNum();
            }
        } else {
            List<ResourceData> list = resourceDataDao.findListByType(type);

            for (ResourceData resourceData : list) {
                count1 += resourceData.getPlayNum();
                count2 += resourceData.getDownloadNum();
            }
        }

        count[0] = count1;
        count[1] = count2;

        return count;
    }
}
